package com.xindacloud.sms.adapter.controller;

import com.xindacloud.sms.adapter.bo.CheckPhoneNumberBO;
import com.xindacloud.sms.adapter.component.BasicInsight;
import com.xindacloud.sms.adapter.dto.SearchMessageDTO;
import com.xindacloud.sms.adapter.dto.SubmitMessageParamDTO;
import com.xindacloud.sms.adapter.dto.ValidNumberParamDTO;
import com.xindacloud.sms.adapter.entity.SmsUser;
import com.xindacloud.sms.adapter.entity.SmsUserAllowOperator;
import com.xindacloud.sms.adapter.exception.ServiceException;
import com.xindacloud.sms.adapter.service.business.ISmsSubmissionRecordService;
import com.xindacloud.sms.adapter.service.business.ISmsUserAllowOperatorService;
import com.xindacloud.sms.adapter.service.business.ISmsUserService;
import com.xindacloud.sms.adapter.service.notify.NotifyExecutor;
import com.xindacloud.sms.adapter.utils.MessageTypeHelp;
import com.xindacloud.sms.adapter.utils.PhoneUtil;
import com.xindacloud.sms.adapter.utils.UnionResultHelp;
import com.xindacloud.sms.adapter.vo.SubmitMessageResultVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;

@Api(tags = {"短信发送接口"})
@RestController
@RequestMapping(value = "/api/v1/adapter/sms")
@Slf4j
public class SubmitMessageController {


    private final ISmsSubmissionRecordService smsSubmissionRecordService;

    private final NotifyExecutor notifyExecutor;

    final BasicInsight basicInsight;

    final ISmsUserService userService;

    @Autowired
    ISmsUserAllowOperatorService userAllowOperatorService;

    @Autowired
    public SubmitMessageController(ISmsSubmissionRecordService smsSubmissionRecordService,
                                   NotifyExecutor notifyExecutor, BasicInsight basicInsight,
                                   ISmsUserService userService) {
        this.smsSubmissionRecordService = smsSubmissionRecordService;
        this.notifyExecutor = notifyExecutor;
        this.basicInsight = basicInsight;
        this.userService = userService;
    }


    @Deprecated
    @ApiOperation(value = "提交短信至队列", response = UnionResultHelp.class)
    @PostMapping(value = "/submit", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    public Object submitMessage(@ApiParam(name = "submitMessageParamDTO", value = "提交短信DTO", required = true)
                                @RequestBody @Valid SubmitMessageParamDTO submitMessageParamDTO,
                                @ApiParam(name = "username", value = "用户名", required = true)
                                @RequestHeader(name = "username") String username,
                                @ApiParam(name = "password", value = "密码", required = true)
                                @RequestHeader(name = "password") String password) {
        return submitResultObject(submitMessageParamDTO, username, password);
    }


    @Deprecated
    @ApiOperation(value = "开放API提交短信至队列", response = UnionResultHelp.class)
    @PostMapping(value = "/open/submit", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    public Object openApiSubmitMessage(@ApiParam(name = "submitMessageParamDTO", value = "提交短信DTO", required = true)
                                       @RequestBody @Valid SubmitMessageParamDTO submitMessageParamDTO,
                                       @ApiParam(name = "username", value = "用户名", required = true)
                                       @RequestHeader(name = "username") String username,
                                       @ApiParam(name = "password", value = "密码", required = true)
                                       @RequestHeader(name = "password") String password) {

        log.info("开放API提交短信");
        final SmsUser smsUser = userService.queryUserInfoFor(username, password);
        if (Objects.isNull(smsUser) || smsUser.getBalance().doubleValue() <= 0) {
            throw new ServiceException("账户余额不足", UnionResultHelp.StatusEnum.Fail.code());
        }

        final List<String> recipients = submitMessageParamDTO.getRecipientList();
        BigDecimal finalPrice = BigDecimal.ZERO;
        for (String recipient : recipients) {
            final CheckPhoneNumberBO phoneNumberVO = PhoneUtil.getPoneNumber(recipient);
            if (Objects.isNull(phoneNumberVO)) {
                throw new ServiceException("存在无效的号码:" + recipient, UnionResultHelp.StatusEnum.Fail.code());
            }
            final SmsUserAllowOperator smsUserAllowOperator = userAllowOperatorService.queryUserAllowOperatorMinPrice(smsUser.getUserId(),
                    phoneNumberVO.getRegion(), String.valueOf(phoneNumberVO.getCountryPrefix()));
            final BigDecimal messagePrice = MessageTypeHelp.calcMessagePrice(smsUserAllowOperator.getPrice(),
                    MessageTypeHelp.calcMessageCount(submitMessageParamDTO.getMessageBody()));

            finalPrice = finalPrice.add(messagePrice);
            if (smsUser.getBalance().doubleValue() < finalPrice.doubleValue()) {
                throw new ServiceException("账户余额不足,不足以抵扣当前短信费用,请先充值.", UnionResultHelp.StatusEnum.Fail.code());
            }
        }

        return submitResultObject(submitMessageParamDTO, username, password);

    }

    @Deprecated
    @NotNull
    private Object submitResultObject(@Valid @RequestBody @ApiParam(name = "submitMessageParamDTO", value = "提交短信DTO", required = true) SubmitMessageParamDTO submitMessageParamDTO, @RequestHeader(name = "username") @ApiParam(name = "username", value = "用户名", required = true) String username, @RequestHeader(name = "password") @ApiParam(name = "password", value = "密码", required = true) String password) {
        try {

            log.info("####提交短信至队列开始时间{}:", UnionResultHelp.getStrTimestamp());
            final String encoding = MessageTypeHelp.isUnicode(submitMessageParamDTO.getMessageBody())
                    ? MessageTypeHelp.MessageTypeEnum.UNICODE.toString()
                    : MessageTypeHelp.MessageTypeEnum.GSM.toString();
            submitMessageParamDTO.setEncoding(encoding);
            submitMessageParamDTO.setMessageCount(MessageTypeHelp.calcMessageCount(submitMessageParamDTO.getMessageBody()));
            notifyExecutor.sendNotifyMessage(submitMessageParamDTO, username, password);
            log.info("####提交短信至队列完毕结束时间:{}", UnionResultHelp.getStrTimestamp());
            return "提交短信成功";
        } catch (Exception e) {
            log.error("提交短信异常:{}", e.getMessage(), e);
            throw new ServiceException("提交短信异常", UnionResultHelp.StatusEnum.Fail.code());
        }
    }


    @ApiOperation(value = "短信查询", response = SubmitMessageResultVO.class)
    @PostMapping(value = "/search", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    public Object searchMessage(@RequestBody SearchMessageDTO searchMessageDTO) {
        return smsSubmissionRecordService.searchMessage(searchMessageDTO);
    }

    @ApiOperation(value = "号码校验", response = List.class)
    @PostMapping(value = "/valid-number", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    public Object validNumber(@RequestBody ValidNumberParamDTO validNumberParamDTO,
                              @ApiParam(name = "username", value = "用户名", required = true)
                              @RequestHeader(name = "username") String username,
                              @ApiParam(name = "password", value = "密码", required = true)
                              @RequestHeader(name = "password") String password) {
        return basicInsight.validNumber(new ArrayList<>(new HashSet<>(validNumberParamDTO.getRecipientList())));
    }
}
